﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using DomainModel;
using Services.Abstract;

namespace Web
{
    public partial class Journal : BasePage
    {
        public IGroupService GroupService { get; set; }
        public IUserService UserService { get; set; }
        public ILessonService LessonService { get; set; }
        public ISubjectService SubjectService { get; set; }
        public IPermissionService PermissionService { get; set; }
        public IDateTimeService DateTimeService { get; set; }
        public ISemesterService SemesterService { get; set; }
        public IStudyYearService StudyYearService { get; set; }
        public IWorkTypeService WorkTypeService { get; set; }
        public IEmailService EmailService { get; set; }

        protected StudySemester SelectedSemester;
        protected Group SelectedGroup;
        protected Subject SelectedSubject;

        private List<StudyYear> _studyYears;
        private List<Group> _groups;
        private List<Subject> _subjects;

        protected new void Page_Load(object sender, EventArgs e)
        {
            if (!PermissionService.CanViewJournal())
            {
                Response.Redirect("/Error/AccessDenied.aspx");
            }

            SelectMenuItem("NavJournal");

            _studyYears = StudyYearService.GetAll().OrderBy(sy => sy.BeginDate).ToList();
            _groups = GroupService.GetAll().OrderBy(g => g.Name).ToList();
            _subjects = SubjectService.GetAll().OrderBy(s => s.Name).ToList();

            try
            {
                long semesterId = long.Parse(Request.QueryString["SemesterId"]);
                SelectedSemester = SemesterService.GetById(semesterId);
            }
            catch (ArgumentNullException) { }
            catch (FormatException) { }
            if (SelectedSemester == null)
                SelectedSemester = SemesterService.GetCurrentSemester();

            try
            {
                long groupId = long.Parse(Request.QueryString["GroupId"]);
                SelectedGroup = GroupService.GetById(groupId);
            }
            catch (ArgumentNullException) { }
            catch (FormatException) { }
            if (SelectedGroup == null)
                SelectedGroup = _groups.First();

            try
            {
                long subjectId = long.Parse(Request.QueryString["SubjectId"]);
                SelectedSubject = SubjectService.GetById(subjectId);
            }
            catch (ArgumentNullException) { }
            catch (FormatException) { }
            if (SelectedSubject == null)
                SelectedSubject = _subjects.First();

            if (!IsPostBack)
            {
                BindDdlSemesters();
                BindDdlGroups();
                BindDdlSubjects();

                DdlSemestersFilter.Items.FindByValue(SelectedSemester.Id.ToString()).Selected = true;
                DdlGroupsFilter.Items.FindByValue(SelectedGroup.Id.ToString()).Selected = true;
                DdlSubjectsFilter.Items.FindByValue(SelectedSubject.Id.ToString()).Selected = true;

                BindListViewStudents();

                BindMarks();
            }
        }

        private void BindDdlSemesters()
        {
            var ds = new List<object>();

            foreach (var studyYear in _studyYears)
            {
                int semesterNo = 1;
                foreach (var semester in studyYear.StudySemesters)
                {
                    ds.Add(new
                    {
                        Id = semester.Id,
                        Name = studyYear.Name + " (" + semesterNo + "-й семестр)",
                    });
                    semesterNo++;
                }
            }

            DdlSemestersFilter.DataSource = ds;
            DdlSemestersFilter.DataValueField = "Id";
            DdlSemestersFilter.DataTextField = "Name";
            DdlSemestersFilter.DataBind();
        }

        private void BindDdlGroups()
        {
            DdlGroupsFilter.DataSource = _groups;
            DdlGroupsFilter.DataValueField = "Id";
            DdlGroupsFilter.DataTextField = "Name";
            DdlGroupsFilter.DataBind();
        }

        private void BindDdlSubjects()
        {
            DdlSubjectsFilter.DataSource = _subjects;
            DdlSubjectsFilter.DataValueField = "Id";
            DdlSubjectsFilter.DataTextField = "Name";
            DdlSubjectsFilter.DataBind();
        }

        private void BindListViewStudents()
        {
            var students = UserService.GetUsers(SelectedGroup).OrderBy(s => s.UserProfile.Fio).ToList();

            var ds = new List<object>();

            int studentNo = 1;
            foreach (var student in students)
            {
                ds.Add(new
                {
                    Id = student.Id,
                    Fio = student.UserProfile.Fio,
                    No = studentNo++,
                });
            }

            ListViewStudents.DataSource = ds;
            ListViewStudents.DataBind();
        }

        private void BindMarks()
        {
            var lessons = LessonService.GetLessons(SelectedSemester, SelectedGroup, SelectedSubject);
            var groupedLessons = lessons.GroupBy(l => new { l.Date, l.TimetableUnit }).Select(g => g.First()).ToList();

            if (lessons.Count == 0)
            {
                MarksTableWrap.InnerText = "Еще не было предметов.";
                return;
            }

            var table = new Table { CssClass = "table-bordered timetable" };
            var thead = new TableHeaderRow { TableSection = TableRowSection.TableHeader };
            foreach (var lesson in groupedLessons)
            {
                var th = new TableHeaderCell { Text = lesson.Date.ToShortDateString() };
                thead.Cells.Add(th);
            }
            table.Rows.Add(thead);

            var tr1 = new TableHeaderRow { TableSection = TableRowSection.TableHeader };

            var td1 = new TableHeaderCell { Text = "Проп." };
            tr1.Cells.Add(td1);

            td1 = new TableHeaderCell { Text = "Ср. бал" };
            tr1.Cells.Add(td1);

            TableResultMarks.Rows.Add(tr1);

            var orderedStudents = UserService.GetUsers(SelectedGroup).OrderBy(s => s.UserProfile.Fio).ToList();
            foreach (var student in orderedStudents)
            {
                var tr = new TableRow();

                foreach (var groupedlesson in groupedLessons)
                {
                    var lesson = lessons.SingleOrDefault(l => l.Student.Id == student.Id && l.Date == groupedlesson.Date && l.TimetableUnit == groupedlesson.TimetableUnit);

                    var td = new TableCell();
                    if (lesson != null)
                    {
                        if (PermissionService.CanChangeMark(lesson))
                        {
                            var tb = new TextBox { ID = "TbMark" + lesson.Id, Text = lesson.Mark, };
                            tb.Attributes["lessonId"] = lesson.Id.ToString();
                            tb.Attributes["onkeydown"] = string.Format("return checkKey(event, {0});", lesson.Id);
                            tb.MaxLength = 1;

                            td.Controls.Add(tb);
                        }
                        else
                        {
                            var lbl = new Label { Text = lesson.Mark, };

                            td.Controls.Add(lbl);
                        }
                    }
                    else
                    {
                        var lbl = new Label { Text = "-" };

                        td.Controls.Add(lbl);
                    }
                    tr.Cells.Add(td);
                }
                table.Rows.Add(tr);

                int missed = LessonService.GetMissedLessonsNumber(SelectedSemester, student, SelectedSubject);
                double avgBall = LessonService.GetAvgBall(SelectedSemester, student, SelectedSubject);

                var tr2 = new TableRow();

                var td2 = new TableCell { Text = missed.ToString() };
                tr2.Cells.Add(td2);

                td2 = new TableCell { Text = avgBall.ToString("0.##") };
                tr2.Cells.Add(td2);

                TableResultMarks.Rows.Add(tr2);
            }

            var tfoot = new TableFooterRow { TableSection = TableRowSection.TableFooter };
            foreach (var lesson in groupedLessons)
            {
                var td = new TableCell();

                var lbl = new Label { Text = "(" + WorkTypeService.GetWorkTypeName(lesson.TimetableUnit.WorkType) + ")" };
                td.Controls.Add(lbl);

                lbl = new Label { Text = "(" + lesson.TimetableUnit.Teacher.UserProfile.Fio + ")" };
                td.Controls.Add(lbl);

                tfoot.Cells.Add(td);
            }
            table.Rows.Add(tfoot);

            MarksTableWrap.Controls.Add(table);
        }

        protected void DdlSemestersFilter_OnSelectedIndexChanged(object sender, EventArgs e)
        {
            string url = string.Format("/Journal.aspx?SemesterId={0}&GroupId={1}&SubjectId={2}", DdlSemestersFilter.SelectedValue, SelectedGroup.Id, SelectedSubject.Id);

            Response.Redirect(url);
        }

        protected void DdlGroupsFilter_OnSelectedIndexChanged(object sender, EventArgs e)
        {
            string url = string.Format("/Journal.aspx?SemesterId={0}&GroupId={1}&SubjectId={2}", SelectedSemester.Id, DdlGroupsFilter.SelectedValue, SelectedSubject.Id);

            Response.Redirect(url);
        }

        protected void DdlSubjectsFilter_OnSelectedIndexChanged(object sender, EventArgs e)
        {
            string url = string.Format("/Journal.aspx?SemesterId={0}&GroupId={1}&SubjectId={2}", SelectedSemester.Id, SelectedGroup.Id, DdlSubjectsFilter.SelectedValue);

            Response.Redirect(url);
        }

        protected void BtnSaveMark_OnClick(object sender, EventArgs e)
        {
            long lessonId;
            try
            {
                lessonId = long.Parse(LessonId.Value);
            }
            catch (Exception)
            {
                ShowSysMsg("Неверный идентификатор занятия.");
                return;
            }

            Lesson lesson = LessonService.GetById(lessonId);
            if (lesson == null)
            {
                ShowSysMsg("Ошибка базы данных. Невозможно найти урок.");
                return;
            }

            string markStr = MarkValue.Value;

            if (string.IsNullOrEmpty(markStr))
            {
                lesson.Mark = "";
            }
            else if (markStr == "1" || markStr == "2" || markStr == "3" || markStr == "4" || markStr == "5")
            {
                lesson.Mark = markStr;
            }
            else
            {
                lesson.Mark = "Н";
            }

            try
            {
                LessonService.SaveOrUpdate(lesson);

                BindMarks();

                string msgBody = "<h1>Уважаемый " + lesson.Student.UserProfile.Fio + "</h1>" +
                    "Вы получили отметку в дневнике: " + lesson.Mark +
                    "</br>по предмету " + lesson.TimetableUnit.Subject.Name +
                    "</br>от преподавателя " + lesson.TimetableUnit.Teacher.UserProfile.Fio +
                    "</br>на " + lesson.TimetableUnit.PairNo.ToString() + "-й паре.";

                EmailService.Send(lesson.Student.Email, "Новая отметка в дневнике", msgBody);

                var parent = UserService.GetParent(lesson.Student);

                msgBody = "<h1>Уважаемый " + parent.UserProfile.Fio + "</h1>" +
                    "Ваш ребенок получил новую отметку в дневнике: " + lesson.Mark +
                    "</br>по предмету " + lesson.TimetableUnit.Subject.Name +
                    "</br>от преподавателя " + lesson.TimetableUnit.Teacher.UserProfile.Fio +
                    "</br>на " + lesson.TimetableUnit.PairNo.ToString() + "-й паре.";

                EmailService.Send(parent.Email, "Новая отметка в дневнике ребенка", msgBody);

                var ctrl = (TextBox)MarksTableWrap.FindControl("TbMark" + lesson.Id);
                ctrl.Focus();

                LessonId.Value = "";
                MarkValue.Value = "";
            }
            catch (Exception ex)
            {
                ShowSysMsg(ex.Message);
            }
        }
    }
}